//////////////////////////////////////
// Fast Container Library           //
// MIT License - Copyright (c) 2012 //
//////////////////////////////////////

#pragma once

#include "common.h"
#include "algobase.h"

FC_NAMESPACE_BEGIN


template <class T>
struct char_traits
{
	typedef T			char_type;
	typedef	int			int_type;
	typedef int			off_type;
	typedef size_t		pos_type;
	//typedef mbstate_t	state_type;

	static bool eq( char_type c1, char_type c2 ) { return c1 == c2; }
	static bool lt( char_type c1, char_type c2 ) { return c1 < c2; }

	static void assign( char_type& c, const char_type& value ) { c = value; }
	static char_type* assign( char_type* s, size_t n, char_type value )
	{
		return fc::fill_n(s, n, value);
	}

	static int compare( const char_type* s1, const char_type* s2, size_t n )
	{
		for( ; n != 0; --n, ++s1, ++s2 )
			if( *s1 != *s2 )
				return (*s1 < *s2) ? -1 : 1;
		return 0;
	}

	static size_t length( const char_type* s )
	{
		size_t n = 0;
		while( *s++ != char_type(0) ) ++n;
		return n;
	}

	static const char_type* find( const char_type* s, size_t n, const char_type& c )
	{
		return fc::find(s, s + n, c);
	}

	static char_type* move( char_type* dest, const char_type* src, size_t n )
	{
		fc::copy_backward(src, src + n, dest);
		return dest;
	}

	static char_type* copy( char_type* dest, const char_type* src, size_t n )
	{
		fc::copy(src, src + n, dest);
		return dest;
	}
};


template <>
struct char_traits<char>
{
	typedef char		char_type;
	typedef	int			int_type;
	typedef int			off_type;
	typedef size_t		pos_type;
	//typedef mbstate_t	state_type;

	static bool eq( char_type c1, char_type c2 ) { return c1 == c2; }
	static bool lt( char_type c1, char_type c2 ) { return (unsigned char)c1 < (unsigned char)c2; }

	static void assign( char_type& c, const char_type& value ) { c = value; }
	static char_type* assign( char_type* s, size_t n, char_type value )
	{
		return (char_type*)::memset(s, (int)value, n);
	}

	static int compare( const char_type* s1, const char_type* s2, size_t n )
	{
		return ::memcmp(s1, s2, n);
	}

	static size_t length( const char_type* s )
	{
		return ::strlen(s);
	}

	static const char_type* find( const char_type* s, size_t n, const char_type& c )
	{
		return (char_type*)::memchr(s, int(c), n);
	}

	static char_type* move( char_type* dest, const char_type* src, size_t n )
	{
		return (char_type*)::memmove(dest, src, n);
	}

	static char_type* copy( char_type* dest, const char_type* src, size_t n )
	{
		return (char_type*)::memcpy(dest, src, n);
	}
};



FC_NAMESPACE_END
